2-5 Hash

hash 和陣列非常相近,唯一不同的是,陣列的索引值都是非負的整數,而 hash 的索引值可以是任何純量,通常我們將 hash 的索引值稱為 key,而將對應的對應的純量則稱為 value,所以整個 hash 可以看成是從 key 到 value 的一種關聯(Association)或映射(Mapping)。hash 的原名是「關聯陣列」(Associative Array),此名字還比較容易反應 hash 的特性,雖然 hash 能翻譯為「雜湊」,但似乎沒辦法反應 hash 的特性,因此在本文中我們還是使用原文 hash。

hash 變數都是以「%」開頭,再加上一些英文字母或數字。下例設定一個簡單的 hash 變數:

%chairs = ("EE"=>"Huang","CS"=>"Huang", "PME"=>"Yang"); 在上例中,"EE" 對應至 "Huang","CS" 也對應至 "Huang",而 "PME" 則對應至 "Yang"。請注意,key 值必須是唯一的(例如上例的 "EE"、"CS"、"PME"),而 value 值則不必是唯一(例如上例的 "Huang"、"Huang"、"Yang")。若要加入一個新的 key-value,可輸入如下: $chairs{"Chem"} = "Chou"; 此時我們即把 Chem => Chou 的對應關係加入了 hash 變數 chairs。若要刪除其中一個對應關係,可用 delete,例如: delete $chairs{"PME"}; 此時 PME => Yang 的對應關係即從 chairs 中刪除了。若要取得所有的 key 或 value 值,可用 key 或 value 函數,舉例如下: %chairs = ("EE"=>"Huang","CS"=>"Huang", "PME"=>"Yang"); @allkeys = keys %chairs; @allvalues = values %chairs; 值得注意的是,Perl 內部的儲存方式並和我們設定 %chairs 的順序無關,因此 @allkeys 雖然可以取得所有的 key 值,但它們的次序並不見得是 ("EE", "CS", "PME"),@allvalues 的次序也不見得是 ("Huang", "Huang", "Yang")。

若要取得 hash 變數的元素個數,直接將 key 函數之結果設定給一個純量變數即可,例如:

%chairs = ("EE"=>"Huang","CS"=>"Huang", "PME"=>"Yang"); $count = keys %chairs; # $count = 3 若要將兩個 hash 變數合併起來,可用下列範例說明: %score{"Tim", "Ann", "Ed"} = {95, 87, 69}; %score2{"Chris", "Sue"} = {30, 50}; %score{key %score2} = values %scores; 另一個更簡單的方法,則是直接將之並排即可: %score = (%score, %score2); 我們也可以利用 reverse 函數將 key-value 的對應關係翻轉過來,使 key 變成 value,value 變成 key,例如: %chairs = ("EE"=>"Huang","CS"=>"Huang", "PME"=>"Yang"); %new = reverse %chairs; 在上例中,由於原先的 value 並不唯一,翻轉成 key 之後,Perl 會自動消去重複的 key,因此原先三個對應關係,在翻轉後只剩下兩個,讀者可以自己實驗看看!

若要取得 hash 變數內所有的對應關係,可用 foreach 迴圈,範例(thash1.pl)如下:

原始檔(thash1.pl):(灰色區域按兩下即可拷貝)
%chairs = ("EE"=>"Huang", "CS"=>"Huang", "PME"=>"Yang");
foreach $key (keys %chairs) {
	print "\$chairs{$key} = $chairs{$key}\n";
}

另一個類似的作法則是使用只能用在 hash 變數的 each 函數,範例(thash2.pl)如下:

原始檔(thash2.pl):(灰色區域按兩下即可拷貝)
%chairs = ("EE"=>"Huang", "CS"=>"Huang", "PME"=>"Yang");
while (($key, $value) = each %chairs) {
	print "\$chairs{$key} = $chairs{$key}\n";
}

以上兩個範例程式,都會產生相同的結果:

$chairs{EE} = Huang $chairs{CS} = Huang $chairs{PME} = Yang

和 hash 相關的函數可整理列表如下:

函數說明
keys取得 hash 變數的所有 key 值
values取得 hash 變數的所有 value 值
delete刪除 hash 變數的某一個對應關係
reverse翻轉 hash 變數的對應關係
each取得 hash 變數的所有對應關係


Perl